<!--
 * @Description: 深入研究节点组件
 * @Author: Auto
 * @Date: 2025-01-27
-->
<template>
  <div 
    class="deep-thinking-node" 
    :class="nodeClass"
    :style="nodeStyle"
    @mousedown="handleNodeMouseDown"
    @dblclick="handleNodeDoubleClick"
  >
    <Handle id="top" type="target" position="top" />
    <Handle id="bottom" type="source" position="bottom" />
    <Handle id="left" type="target" position="left" />
    <Handle id="right" type="source" position="right" />
    
    <!-- 删除按钮 -->
    <div class="delete-btn" @click.stop="handleDelete" title="删除节点">
      <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M11 3.5L3 11.5M3 3.5L11 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
      </svg>
    </div>
    
    <!-- 添加节点菜单按钮（仅在root和person-info类型显示） -->
    <div 
      v-if="showAddMenu" 
      class="add-menu-btn" 
      @click.stop="toggleMenu($event)"
      title="添加节点"
    >
      <EllipsisOutlined />
      <!-- 下拉菜单 -->
      <div v-if="showMenu" class="add-menu-dropdown" @click.stop>
        <div class="menu-item" @click="handleAddNode('person-info')">
          <span>人员基本信息</span>
        </div>
        <div class="menu-item" @click="handleAddNode('text')">
          <span>文本框</span>
        </div>
        <div class="menu-item" @click="handleAddNode('table')">
          <span>列表信息</span>
        </div>
        <div class="menu-item" @click="handleAddNode('person-trajectory')">
          <span>人像轨迹</span>
        </div>
      </div>
    </div>
    
    <!-- 调整大小拖拽点 -->
    <div 
      class="resize-handle" 
      @mousedown.stop="handleResizeStart"
      title="拖拽调整大小"
    ></div>
    
    <!-- 进度条模式 -->
    <div v-if="progress < 100" class="progress-container">
      <div class="progress-bar-wrapper">
        <div class="progress-bar" :style="{ width: `${progress}%` }"></div>
      </div>
      <div class="progress-text">{{ Math.round(progress) }}%</div>
    </div>
    
    <!-- 节点内容模式 -->
    <template v-else>
      <div class="node-content-wrapper">
        <div class="node-icon" :style="iconStyle">
          <span v-if="icon">{{ icon }}</span>
          <div v-else class="icon-placeholder"></div>
        </div>
        <div class="node-content">
          <div v-if="statusLabel" class="status-label">{{ statusLabel }}</div>
          <div class="node-text">{{ label }}</div>
        </div>
      </div>
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, onMounted, onUnmounted, nextTick } from 'vue'
import { Handle } from '@vue-flow/core'
import { EllipsisOutlined } from '@ant-design/icons-vue'

// 注册Handle组件
Handle.name = 'Handle'

interface Props {
  label: string
  type?: 'root' | 'missing' | 'conclusion' | 'thinking' | 'evaluation' | 'person-info'
  status?: 'info-missing' | 'conclusion-pending' | 'thinking' | 'evaluation'
  icon?: string
  progress?: number // 进度 0-100
  nodeId?: string // 节点ID，用于删除
  width?: number // 节点宽度
  height?: number // 节点高度
  selected?: boolean // 是否选中
}

const props = withDefaults(defineProps<Props>(), {
  type: 'root',
  status: undefined,
  icon: undefined,
  progress: 100,
  nodeId: '',
  width: undefined,
  height: undefined,
  selected: false
})

// 定义事件
const emit = defineEmits<{
  delete: [nodeId: string]
  resize: [nodeId: string, width: number, height: number]
  addNode: [nodeId: string, nodeType: 'person-info' | 'text' | 'table' | 'person-trajectory']
}>()

// 是否显示添加菜单按钮（仅在root和person-info类型显示）
const showAddMenu = computed(() => {
  return props.type === 'root' || props.type === 'person-info'
})

// 菜单显示状态
const showMenu = ref(false)

// 切换菜单显示
const toggleMenu = (e: MouseEvent) => {
  showMenu.value = !showMenu.value
}

// 处理添加节点
const handleAddNode = (nodeType: 'person-info' | 'text' | 'table' | 'person-trajectory') => {
  if (props.nodeId) {
    emit('addNode', props.nodeId, nodeType)
    showMenu.value = false
  }
}

// 点击外部关闭菜单
onMounted(() => {
  const handleClickOutside = (e: MouseEvent) => {
    if (showMenu.value) {
      const target = e.target as HTMLElement
      if (!target.closest('.add-menu-btn') && !target.closest('.add-menu-dropdown')) {
        showMenu.value = false
      }
    }
  }
  document.addEventListener('click', handleClickOutside)
  
  onUnmounted(() => {
    document.removeEventListener('click', handleClickOutside)
  })
})

// 节点样式
const nodeStyle = computed(() => {
  const style: Record<string, string> = {}
  if (props.width !== undefined) {
    style.width = `${props.width}px`
  }
  if (props.height !== undefined) {
    style.height = `${props.height}px`
  }
  return style
})

// 处理删除
const handleDelete = () => {
  if (props.nodeId) {
    emit('delete', props.nodeId)
  }
}

// 处理节点鼠标按下事件 - 确保拖拽功能正常
const handleNodeMouseDown = (e: MouseEvent) => {
  // 如果点击的是按钮或调整大小拖拽点，不阻止事件
  const target = e.target as HTMLElement
  if (
    target.closest('.delete-btn') ||
    target.closest('.add-menu-btn') ||
    target.closest('.add-menu-dropdown') ||
    target.closest('.resize-handle') ||
    target.closest('.vue-flow__handle')
  ) {
    // 这些元素的事件已经通过 @click.stop 或 @mousedown.stop 处理了
    return
  }
  // 其他区域允许拖拽，不阻止默认行为
}

// 处理节点双击事件
const handleNodeDoubleClick = (e: MouseEvent) => {
  // 如果点击的是按钮或调整大小拖拽点，不处理双击
  const target = e.target as HTMLElement
  if (
    target.closest('.delete-btn') ||
    target.closest('.add-menu-btn') ||
    target.closest('.add-menu-dropdown') ||
    target.closest('.resize-handle') ||
    target.closest('.vue-flow__handle')
  ) {
    return
  }
  console.log('Node double clicked in component:', props.nodeId)
  // 可以在这里添加节点编辑逻辑
  // 注意：事件会继续冒泡到 Vue Flow 的 @node-dblclick 事件
}

// 调整大小相关状态
const isResizing = ref(false)
const startX = ref(0)
const startY = ref(0)
const startWidth = ref(0)
const startHeight = ref(0)

// 开始调整大小
const handleResizeStart = (e: MouseEvent) => {
  e.preventDefault()
  e.stopPropagation()
  
  isResizing.value = true
  startX.value = e.clientX
  startY.value = e.clientY
  startWidth.value = props.width || 250
  startHeight.value = props.height || 100
  
  document.addEventListener('mousemove', handleResizeMove)
  document.addEventListener('mouseup', handleResizeEnd)
  
  // 防止文本选择
  document.body.style.userSelect = 'none'
  document.body.style.cursor = 'nwse-resize'
}

// 调整大小过程中
const handleResizeMove = (e: MouseEvent) => {
  if (!isResizing.value) return
  
  const deltaX = e.clientX - startX.value
  const deltaY = e.clientY - startY.value
  
  const newWidth = Math.max(180, startWidth.value + deltaX) // 最小宽度180px
  const newHeight = Math.max(80, startHeight.value + deltaY) // 最小高度80px
  
  emit('resize', props.nodeId, newWidth, newHeight)
}

// 结束调整大小
const handleResizeEnd = () => {
  isResizing.value = false
  document.removeEventListener('mousemove', handleResizeMove)
  document.removeEventListener('mouseup', handleResizeEnd)
  
  // 恢复文本选择和鼠标样式
  document.body.style.userSelect = ''
  document.body.style.cursor = ''
}

// 组件卸载时清理事件监听
onUnmounted(() => {
  document.removeEventListener('mousemove', handleResizeMove)
  document.removeEventListener('mouseup', handleResizeEnd)
})

const nodeClass = computed(() => {
  return {
    [`node-${props.type}`]: true,
    [`status-${props.status}`]: props.status,
    'node-selected': props.selected
  }
})

const iconStyle = computed(() => {
  const colors: Record<string, string> = {
    root: '#409EFF',
    missing: '#ff4d4f',
    conclusion: '#52c41a',
    thinking: '#1890ff',
    evaluation: '#2f54eb'
  }
  return {
    backgroundColor: colors[props.type] || colors.root
  }
})

const statusLabel = computed(() => {
  const labels: Record<string, string> = {
    'info-missing': '信息缺失',
    'conclusion-pending': '结论待完善',
    'thinking': '正在思考中...',
    'evaluation': '评估'
  }
  return props.status ? labels[props.status] : ''
})
</script>

<style scoped lang="less">
.deep-thinking-node {
  display: flex;
  align-items: flex-start;
  padding: 10px 8px;
  border-radius: 8px;
  min-width: 180px;
  width: 250px; // 默认宽度
  min-height: 80px;
  height: auto; // 默认高度自适应
  max-height: none; // 允许高度超过默认值
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.3s ease, border-color 0.3s ease; // 只过渡阴影和边框颜色，不过渡宽高
  cursor: grab; // 改为grab，提示可以拖拽
  position: relative; // 确保删除按钮和调整大小点可以绝对定位
  overflow: visible; // 改为visible，确保按钮不被裁剪
  box-sizing: border-box; // 确保padding包含在宽高内
  
  &:active {
    cursor: grabbing; // 拖拽时显示grabbing
  }

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    // 移除transform，避免影响Handle位置
    // transform: translateY(-2px);
  }

  // 选中状态样式
  &.node-selected {
    border-color: #1890ff;
    border-width: 3px;
    box-shadow: 0 0 0 3px rgba(24, 144, 255, 0.2), 0 4px 16px rgba(24, 144, 255, 0.3);
  }

  // 确保Handle始终可见且可交互
  :deep(.vue-flow__handle) {
    width: 4px !important;
    height: 4px !important;
    min-width: 4px !important;
    min-height: 4px !important;
    background: #409EFF !important;
    border: 2px solid #ffffff !important;
    border-radius: 50% !important;
    z-index: 1000 !important; // 提高z-index确保在最上层
    opacity: 0.9;
    transition: opacity 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease; // 只过渡颜色和阴影，不过渡transform
    cursor: crosshair !important; // 改变鼠标样式，提示可连接
    pointer-events: auto !important; // 确保可以点击
    
    // 使用padding增大点击区域，但不改变视觉大小
    padding: 4px !important;
    margin: -4px !important;
    box-sizing: content-box !important;

    &:hover {
      opacity: 1 !important;
      // 不改变大小和位置，只改变颜色和阴影
      background: #1890ff !important;
      box-shadow: 0 0 8px rgba(24, 144, 255, 0.6) !important;
      z-index: 1001 !important;
      // 不添加transform，避免位置移动
    }
    
    // 确保Handle不受节点transform影响
    position: absolute !important;
  }

  // 删除按钮样式
  .delete-btn {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 4px;
    cursor: pointer;
    z-index: 1002;
    opacity: 1; // 一直显示
    transition: background-color 0.2s ease;
    color: #8c8c8c;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

    &:hover {
      background: #ff4d4f;
      color: #ffffff;
    }
  }

  // 添加节点菜单按钮
  .add-menu-btn {
    position: absolute !important;
    top: 4px !important;
    right: 28px !important; // 放在删除按钮左侧4px：删除按钮right:4px + width:20px + 间距4px = 28px
    width: 20px !important;
    height: 20px !important;
    display: flex !important;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.95) !important;
    border-radius: 4px;
    cursor: pointer;
    z-index: 1003 !important; // 提高层级，确保在删除按钮之上
    opacity: 1 !important; // 一直显示，强制显示
    visibility: visible !important; // 确保可见
    transition: background-color 0.2s ease;
    color: #8c8c8c !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) !important;
    pointer-events: auto !important; // 确保可以点击
    border: 1px solid rgba(0, 0, 0, 0.1); // 添加边框，更容易看到

    &:hover {
      background: #409EFF !important;
      color: #ffffff !important;
      border-color: #409EFF !important;
    }

    .add-menu-dropdown {
      position: absolute; // 相对于按钮定位
      top: calc(100% + 4px); // 紧贴按钮下方4px
      left: 0; // 右对齐到按钮右边缘
      background: #ffffff;
      border-radius: 4px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
      min-width: 140px;
      z-index: 10000; // 提高层级确保在最上层
      overflow: hidden;
      margin: 0; // 移除所有默认margin
      padding: 0; // 移除默认padding
      transform: none;

      .menu-item {
        padding: 8px 12px;
        cursor: pointer;
        font-size: 14px;
        color: #262626;
        transition: background-color 0.2s ease;
        white-space: nowrap; // 防止文字换行

        &:hover {
          background: #f0f0f0;
        }

        &:not(:last-child) {
          border-bottom: 1px solid #f0f0f0;
        }
      }
    }
  }

  // 调整大小拖拽点样式
  .resize-handle {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 12px;
    height: 12px;
    background: #409EFF;
    border: 2px solid #ffffff;
    border-radius: 50%;
    cursor: nwse-resize;
    z-index: 1002;
    opacity: 0;
    transition: opacity 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
    transform: translate(50%, 50%); // 居中定位在右下角

    &:hover {
      opacity: 1 !important;
      background: #1890ff;
      box-shadow: 0 0 8px rgba(24, 144, 255, 0.6);
    }

    &:active {
      background: #0050b3;
    }
  }

  &:hover .resize-handle {
    opacity: 0.8;
  }

  .node-content-wrapper {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: flex-start;
    box-sizing: border-box;
  }

  .node-icon {
    width: 24px;
    height: 24px;
    min-width: 24px;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 12px;
    font-size: 14px;
    color: #ffffff;
    flex-shrink: 0;

    .icon-placeholder {
      width: 100%;
      height: 100%;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      border-radius: 4px;
    }
  }

  .node-content {
    flex: 1;
    min-width: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    box-sizing: border-box;

    .status-label {
      font-size: 12px;
      font-weight: 600;
      margin-bottom: 4px;
      color: #666;
      flex-shrink: 0;
    }

    .node-text {
      font-size: 14px;
      line-height: 1.5;
      word-wrap: break-word;
      word-break: break-all;
      color: #262626;
      flex: 1;
      overflow-y: auto; // 内容超出时可滚动
      min-height: 0; // 确保flex子元素可以缩小
    }
  }
}

// 节点类型样式
.node-root {
  background: #ffffff;
  border: 2px solid #409EFF;
}

.node-missing {
  background: #fff1f0;
  border: 2px solid #ff4d4f;
}

.node-conclusion {
  background: #f6ffed;
  border: 2px solid #52c41a;
}

.node-thinking {
  background: #e6f7ff;
  border: 2px solid #1890ff;
}

.node-evaluation {
  background: #f0f5ff;
  border: 2px solid #2f54eb;
}

// 进度条样式
.progress-container {
  width: 100%;
  height: 100%;
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 200px;
  min-height: 80px;
  box-sizing: border-box;
}

.progress-bar-wrapper {
  width: 100%;
  height: 8px;
  background: #f0f0f0;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 12px;
  position: relative;
}

.progress-bar {
  height: 100%;
  background: linear-gradient(90deg, #409EFF 0%, #1890ff 100%);
  border-radius: 4px;
  transition: width 0.1s linear;
  position: relative;
  overflow: hidden;

  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background: linear-gradient(
      90deg,
      transparent,
      rgba(255, 255, 255, 0.3),
      transparent
    );
    animation: shimmer 1.5s infinite;
  }
}

@keyframes shimmer {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

.progress-text {
  font-size: 14px;
  font-weight: 600;
  color: #409EFF;
}
</style>
